package org.batatasframework.expression;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class CommandExpressionExtra extends CommandExpression{
	
	/** 只有附加参数才支持相同的定义 */
	private final Map<String, List<CommandExpressionArgument>> multipleValues = new HashMap<>();
	private final Named name;
	
//	public CommandExpressionExtra(ExpressionClause se, String... argNames) throws Exception{
//		this(se.getName().toString(), se.split(COMMAND_ARGUMENT_SEPARATOR), argNames);
//	}

	public CommandExpressionExtra(ExpressionClause se, 
			String[] argNames, 
//			List<ExpressionClause> sources, 
			String...extras) throws Exception{
//		this(se.getName().toString(), se.split(COMMAND_ARGUMENT_SEPARATOR), argNames);
		super(se.getString().split(COMMAND_ARGUMENT_SEPARATOR), argNames);
		this.name = se.getName();
		extra(se, extras);
	}
	
//	public CommandExpressionExtra(String name, String[] args, String... argNames) throws Exception{
//		super(args, argNames);
//		this.name = name;
//	}

	/** 哪一个指令支持多个定义的，调用的时候是很清楚的，所以这里不需要再考虑调用者未知道是否多个定义的情况。 */
	public CommandExpressionArgument[] getArray(String argName){
		List<CommandExpressionArgument> cis = multipleValues.get(argName);
		if(null != cis){
			return cis.toArray(new CommandExpressionArgument[cis.size()]);
		}
		
		CommandExpressionArgument cv = values.get(argName);
		if(null != cv){
			return new CommandExpressionArgument[]{ cv };
		}
		
		return new CommandExpressionArgument[0];
	}
	
	/**
	 * <pre>
	 * 附加的参数，即可以通过别一个表达式来加载的数据
	 * 用来解析如：
	 * A1 = ....
	 * A1.options = ...
	 * 这种情况的，这里的参数："extras" 即"A1.options"中的"options"
	 * 注意：是可能存在多个"options"的定义的
	 * 
	 * 这个函数也可以不被调用，如果是非直接的定义的话
	 * </pre>
	 */
	private CommandExpressionExtra extra(ExpressionClause ec, String...extras) throws Exception{
		for(String extra : extras){
			String extraKey = Named.adjust(extra);
			String extraName = Named.concat(name.getName(), extraKey);
			ExpressionValue subev = ec.getSub(extraName);
			
			if(null != subev){
				/*
				 * 使用附加的参数，是可以重新指定原来指令的参数的，如：
				 * 原来参数里已经指定了name，那么这里可以重新进行指定。
				 * comm = name xxx
				 * comm.name = yyy
				 * 那么，最后取到的name的值为"yyy"
				 */
				CommandExpressionArgument citem = new CommandExpressionArgument(
						extraName, 
						subev.getValue(), 
						subev.getExtra());
				
				CommandExpressionArgument oitme = values.put(extraKey, citem);
				if(oitme != null){
					List<CommandExpressionArgument> mvs = multipleValues.get(extraKey);
					if(null == mvs){
						mvs = new ArrayList<>();
						mvs.add(oitme);
					}
					mvs.add(citem);
				}
			}
//			
//			//处理名字的规则，如果已经定义了".xxx"，则不需要再加"."
//			String extraName = name;
//			if(extra.charAt(0) != '.'){
//				extraName += '.';
//				extraKey = extra;
//			}else{
//				extraKey = extra.substring(1);
//			}
//			extraName += extra;
//			for(int i = sources.size() - 1; i >= 0; i--){
//				ExpressionClause se = sources.get(i);
//				if(se.getName().equals(extraName)){
//					/*
//					 * 使用附加的参数，是可以重新指定原来指令的参数的，如：
//					 * 原来参数里已经指定了name，那么这里可以重新进行指定。
//					 * comm = name xxx
//					 * comm.name = yyy
//					 * 那么，最后取到的name的值为"yyy"
//					 */
//					CommandExpressionArgument citem = new CommandExpressionArgument(extraName, se.getValue(), se.getExtra());
//					
//					CommandExpressionArgument oitme = values.put(extraKey, citem);
//					if(oitme != null){
//						List<CommandExpressionArgument> mvs = multipleValues.get(extraKey);
//						if(null == mvs){
//							mvs = new ArrayList<>();
//							mvs.add(oitme);
//						}
//						mvs.add(citem);
//					}
//					
//					sources.remove(i);
//				}
//			}
		}
		return this;
	}
	
}
